/*
 * Copyright (C) 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package br.quest.adapters;

import br.quest.AbstractModel;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public abstract class QuestDbAdapter {

    private static final String DATABASE_NAME = "my_daily_quest";
    private static final int DATABASE_VERSION = 1;
    private static final String TAG = "QuestDbAdapter";

    protected DatabaseHelper mDbHelper;
    protected SQLiteDatabase mDb;
    protected Context mCtx;

    /**
     * Open the database. If it cannot be opened, try to create a new instance of the database. If it cannot be created,
     * throw an exception to signal the failure
     * 
     * @return this (self reference, allowing this to be chained in an initialization call)
     * @throws SQLException if the database could be neither opened or created
     */
    protected QuestDbAdapter open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }

    /**
     * Closes the database. In order to access its data again, you'll need to call open().
     */
    public void close() {
        mDbHelper.close();
    }

    /**
     * Returns the writable database object for this class.
     */
    public SQLiteDatabase getDb() {
        if (!mDb.isOpen()) {
            throw new RuntimeException("The database is not opened yet.");
        }
        return this.mDb;
    }

    /**
     * Runs a simple SELECT with conditions on a specified model.
     * 
     * @param model An instance os AbstractModel.
     * @param where A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE
     *        itself). Passing null will return all rows for the given table.
     * @param args You may include ?s in selection, which will be replaced by the values from selectionArgs, in order
     *        that they appear in the selection. The values will be bound as Strings.
     * @return A Cursor object, which is positioned before the first entry.
     */
    public Cursor basicSelect(AbstractModel model, String where, String[] args) {
        return getDb().query(model.getTableName(), model.getColumns(), where, args, null, null, null);
    }

    /**
     * Runs a SELECT with conditions and ordering on a specified model.
     * 
     * @param model An instance os AbstractModel.
     * @param where A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE
     *        itself). Passing null will return all rows for the given table.
     * @param args You may include ?s in selection, which will be replaced by the values from selectionArgs, in order
     *        that they appear in the selection. The values will be bound as Strings.
     * @param order How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing
     *        null will use the default sort order, which may be unordered.
     * @return A Cursor object, which is positioned before the first entry.
     */
    public Cursor orderedSelect(AbstractModel model, String where, String[] args, String order) {
        return getDb().query(model.getTableName(), model.getColumns(), where, args, null, null, order);
    }

    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // db.execSQL(Leaderboard.getTableCreationSQL());
            // db.execSQL(Pergunta.getTableCreationSQL());
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion
                    + ", which will destroy all old data");
            // db.execSQL("DROP TABLE IF EXISTS " + Leaderboard.getTableName());
            // db.execSQL("DROP TABLE IF EXISTS " + Pergunta.getTableName());
            onCreate(db);
        }
    }
}
